热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

循环结构与零钱问题:多题型综合解析与应用

篇首语:本文由编程笔记#小编为大家整理,主要介绍了各题型归纳总结相关的知识,希望对你有一定的参考价值。 文章目录 二分两种代码模板代码1代码2 思考有重复元素的情况山峰数组 动态规划从题目

篇首语:本文由编程笔记#小编为大家整理,主要介绍了各题型归纳总结相关的知识,希望对你有一定的参考价值。



文章目录


  • 二分
    • 两种代码模板
      • 代码1
      • 代码2

    • 思考
      • 有重复元素的情况
      • 山峰数组


  • 动态规划
    • 从题目中辨识是否用DP
      • 重复子问题
        • 剑指 Offer 46. 把数字翻译成字符串
        • 91. 解码方法

      • 最优子结构
        • 322. 零钱兑换
        • 279. 完全平方数
        • 343. 整数拆分
        • 377. 组合总和 Ⅳ

      • ==无后效性【多阶段、有约束 的决策最优化问题】==
        • 不同路径
        • 打家劫舍



  • 贪心


二分

两种代码模板


代码1


  • 代码1:在循环中查找元素
    适合知道num[mid]等于什么,才能得到结果的情况

public class Solution

// 「力扣」第 704 题:二分查找
public int search(int[] nums, int target)
int len = nums.length;
int left = 0;
int right = len - 1;
// 目标元素可能存在在区间 [left, right]
//区间还剩一个元素时,继续循环
while (left <&#61; right)
// 推荐的写法是 int mid &#61; left &#43; (right - left) / 2;
int mid &#61; (left &#43; right) / 2;
if (nums[mid] &#61;&#61; target)
return mid;
else if (nums[mid] < target)
// 目标元素可能存在在区间 [mid &#43; 1, right]
left &#61; mid &#43; 1;
else
// 目标元素可能存在在区间 [left, mid - 1]
right &#61; mid - 1;


return -1;



代码2


  • 代码2&#xff08;1&#xff09;&#xff1a;在循环体中排除目标元素一定不存在的区间
    适合 不知道num[mid]等于什么 才能得到结果&#xff0c;但知道什么情况下可以缩小区间&#xff0c;的情况。
    使用 if (nums[mid]

public class Solution

// 「力扣」第 704 题&#xff1a;二分查找
public int search(int[] nums, int target)
int len &#61; nums.length;
int left &#61; 0;
int right &#61; len - 1;
// 目标元素可能存在在区间 [left, right]
//区间还剩一个元素时&#xff0c;退出循环
while (left < right)
int mid &#61; left &#43; (right - left) / 2;
//这里注意使用nums[mid]
//若使用nums[mid] > target,则mid需要上取整&#xff1b;
if (nums[mid] < target)
// 下一轮搜索区间是 [mid &#43; 1, right]
left &#61; mid &#43; 1;
else
// 下一轮搜索区间是 [left, mid]
right &#61; mid;


if (nums[left] &#61;&#61; target)
return left;

return -1;



  • 代码2&#xff08;2&#xff09;&#xff1a;在循环体中排除目标元素一定不存在的区间

使用if (nums[mid] > target) 判断&#xff1b;会出现left &#61; mid&#xff1b;mid需要上取整:int mid &#61; left &#43; (right - left &#43; 1) / 2;防止死循环

即&#xff0c;出现left &#61; mid情况&#xff0c;mid需向上取整int mid &#61; left &#43; (right - left &#43; 1) / 2;防止死循环。

public class Solution

// 「力扣」第 704 题&#xff1a;二分查找
public int search(int[] nums, int target)
int len &#61; nums.length;
int left &#61; 0;
int right &#61; len - 1;
while (left < right)
int mid &#61; left &#43; (right - left &#43; 1) / 2;
if (nums[mid] > target)
// 下一轮搜索区间是 [left, mid - 1]
right &#61; mid - 1;
else
// 下一轮搜索区间是 [mid, right]
left &#61; mid;


if (nums[left] &#61;&#61; target)
return left;

return -1;



思考

二分的思想是&#xff0c;通过num[mid]与一个target对比&#xff0c;来缩小区间&#xff0c;


  • 当给定target时&#xff0c;自然与target比较&#xff1b;
  • 当未给定target时&#xff0c;找那些和mid比较 能产生缩小区间效果的元素&#xff0c;如&#xff1a;左右边界常作为target&#xff0c;

有重复元素的情况

针对有重复的情况&#xff0c;是将下面两种**无重复情况**下的划分&#xff1a;
nums[l] <&#61; nums[mid]
nums[l] > nums[mid])
改为下面三种划分&#xff0c;将等于的情况单独提取出来&#xff0c;【适合重复情况】
nums[l] < nums[mid]
nums[l] &#61;&#61; nums[mid] //若nums[l]不是目标值&#xff0c;因为相等&#xff0c;所以可以缩小一个范围&#xff0c;即l&#43;&#43;;
nums[l] > nums[mid])

在有序数组中进行查找一个数&#xff08;二分下标&#xff09;

在整数范围内查找一个整数&#xff08;二分答案&#xff09;


山峰数组

arr[mid] 与 arr[mid &#43; 1]比较


动态规划

找题目中的约束条件&#xff0c;然后根据约束条件定义状态



  • 动态规划的用途&#xff1a;求解多阶段决策问题
    动态规划解决的是这样一类问题&#xff1a;多阶段决策问题。这里的「阶段」就是生活语言&#xff1a;解决一个问题分很多步骤&#xff0c;每一个步骤又有很多种选择&#xff0c;这一点和「回溯算法」是一样的
    通常可以把多阶段决策问题画成一张树形图

  • 动态规划与回溯算法的区别
    「动态规划」与「回溯算法」在问题问法上的区别是&#xff1a;「动态规划」问题通常只问结果&#xff0c;即只问最优值是多少&#xff0c;或者问解决方案的个数&#xff0c;而不问具体解&#xff08;具体的解决方案&#xff09;是什么&#xff1b;
    「回溯算法」问题通常让我们给出一个问题的所有解决方案&#xff0c;要求我们返回的是一个嵌套列表



能够使用动态规划解决的问题&#xff0c;一定可以使用回溯算法解决。但是我们要清楚一个事实&#xff1a;回溯算法的时间复杂度很高。在只问最优值是多少的场景下&#xff0c;没有必要记录每个阶段的每一个步骤。动态规划方法很多时候的意义在于评估算法的上限。



从题目中辨识是否用DP


重复子问题


剑指 Offer 46. 把数字翻译成字符串

求&#xff1a;计算一个数字有多少种不同的翻译方法。
只是求有多少种&#xff0c;而不是求出每种的解决方案&#xff0c;即DP。【若求所有解决方案&#xff0c;则用回溯】


91. 解码方法

求&#xff1a;请计算并返回 解码 方法的 总数
只是求有多少种&#xff0c;而不是求出每种的解决方案&#xff0c;即DP。【若求所有解决方案&#xff0c;则用回溯】


最优子结构



它们的问法都一样&#xff1a;求解一个问题的最优值是多少&#xff0c;但没有问最优值是怎么来的。以后遇到这样的问题&#xff0c;需要有一定敏感&#xff0c;可能这个问题考察的是动态规划&#xff08;还有可能考察广度优先遍历、贪心算法&#xff09;。
分析最优子结构的重要方法依然是&#xff1a;通过研究具体的例子&#xff0c;画图分析。



322. 零钱兑换


279. 完全平方数


343. 整数拆分


377. 组合总和 Ⅳ



对于 nums &#61; [1,2,3], target &#61; 4
dp[4] &#61; dp[4 - 1] &#43; dp[4 - 2] &#43; dp[4 - 3]
即&#xff0c;
dp[target ] &#61; dp[target - nums[0] ] &#43; dp[target - nums[1] ] &#43; dp[target - nums[2] ] &#43; …【target - nums[2] >&#61;0)】


class Solution
public int combinationSum4(int[] nums, int target)
int[] dp &#61; new int[target &#43; 1];
//dp[0]没实际意思&#xff0c;由dp[1] &#61; 1 &#61; dp[0]推出&#xff1b;
dp[0] &#61; 1;
for(int j &#61; 1 ; j <&#61; target ; j&#43;&#43;)
for(int i &#61; 0 ; i < nums.length ; i&#43;&#43;)
if(j >&#61; nums[i]) dp[j] &#61; dp[j] &#43; dp[j - nums[i]];


return dp[target];



无后效性【多阶段、有约束 的决策最优化问题】


不同路径


  • 只需求出路径个数&#xff0c;不需求出具体方案&#xff1b;

打家劫舍


  • 题目只问最优值&#xff0c;并没有问最优解&#xff0c;因此可以考虑使用「动态规划」
  • 约束条件&#xff1a;在不触动警报装置的情况下&#xff0c;
    即分一个房子偷或不偷两种情况&#xff1b;

贪心



推荐阅读
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • Go语言中的高效排序与搜索算法解析
    在探讨Go语言中高效的排序与搜索算法时,本文深入分析了Go语言提供的内置排序功能及其优化策略。通过实例代码,详细讲解了如何利用Go语言的标准库实现快速、高效的排序和搜索操作,为开发者提供了实用的编程指导。 ... [详细]
  • 如何将PHP文件上传至服务器及正确配置服务器地址 ... [详细]
  • 在稀疏直接法视觉里程计中,通过优化特征点并采用基于光度误差最小化的灰度图像线性插值技术,提高了定位精度。该方法通过对空间点的非齐次和齐次表示进行处理,利用RGB-D传感器获取的3D坐标信息,在两帧图像之间实现精确匹配,有效减少了光度误差,提升了系统的鲁棒性和稳定性。 ... [详细]
  • 如何在 Java LinkedHashMap 中高效地提取首个或末尾的键值对? ... [详细]
  • 全面解析Java虚拟机:内存模型深度剖析 ... [详细]
  • 题目描述:小K不幸被LL邪教洗脑,洗脑程度之深使他决定彻底脱离这个邪教。在最终离开前,他计划再进行一次亚瑟王游戏。作为最后一战,他希望这次游戏能够尽善尽美。众所周知,亚瑟王游戏的结果很大程度上取决于运气,但通过合理的策略和算法优化,可以提高获胜的概率。本文将详细解析洛谷P3239 [HNOI2015] 亚瑟王问题,并提供具体的算法实现方法,帮助读者更好地理解和应用相关技术。 ... [详细]
  • 在Python编程中,掌握高级技巧对于提升代码效率和可读性至关重要。本文重点探讨了生成器和迭代器的应用,这两种工具不仅能够优化内存使用,还能简化复杂数据处理流程。生成器通过按需生成数据,避免了大量数据加载对内存的占用,而迭代器则提供了一种优雅的方式来遍历集合对象。此外,文章还深入解析了这些高级特性的实际应用场景,帮助读者更好地理解和运用这些技术。 ... [详细]
  • 深入解析零拷贝技术(Zerocopy)及其应用优势
    零拷贝技术(Zero-copy)是Netty框架中的一个关键特性,其核心在于减少数据在操作系统内核与用户空间之间的传输次数。通过避免不必要的内存复制操作,零拷贝显著提高了数据传输的效率和性能。本文将深入探讨零拷贝的工作原理及其在实际应用中的优势,包括降低CPU负载、减少内存带宽消耗以及提高系统吞吐量等方面。 ... [详细]
  • 探索JavaScript倒计时功能的三种高效实现方法及代码示例 ... [详细]
  • 在Laravel中实现PHP对JSON数据的发布与处理 ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • 在 Android 开发中,通过合理利用系统通知服务,可以显著提升应用的用户交互体验。针对 Android 8.0 及以上版本,开发者需首先创建并注册通知渠道。本文将详细介绍如何在应用中实现这一功能,包括初始化通知管理器、创建通知渠道以及发送通知的具体步骤,帮助开发者更好地理解和应用这些技术细节。 ... [详细]
  • C#编程指南:实现列表与WPF数据网格的高效绑定方法 ... [详细]
author-avatar
艾米27
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有